﻿using Caliburn.Micro;
using GetMan.Configs;
using GetMan.Core.Helpers;
using GetMan.Core.infrastructure.IViewModels;
using GetMan.Core.NLogRender;
using MapsterMapper;
using NLog;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace GetMan
{
    public class GetManBootstrapper : BootstrapperBase
    {
        private static CompositionContainer container;
        private readonly Logger Logger;


        public GetManBootstrapper()
        {
            NLogRenderRegister.Register();
            Logger = NLog.LogManager.GetCurrentClassLogger();
            NLog.LogManager.Setup().LoadConfigurationFromFile("nlog.config");
            Initialize();
        }


        protected override void Configure()
        {
            try
            {
                Logger.Info("配置MEF开始");
                var baseDir = AppDomain.CurrentDomain.BaseDirectory;
                //AssemblySource.Instance.Add(Assembly.LoadFile(System.IO.Path.Combine(baseDir, @"*.dll")));
                var catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new AssemblyCatalog(typeof(GetManBootstrapper).Assembly));
                container = new CompositionContainer(catalog);

                var batch = new CompositionBatch();
                batch.AddExportedValue<IWindowManager>(new WindowManager());
                batch.AddExportedValue<IEventAggregator>(new EventAggregator());
                batch.AddExportedValue(container);

                //注册数据库
                IFreeSql fsql = AddDb();
                batch.AddExportedValue(fsql);

                //配置映射工具类
                var mapper = new Mapper();
                batch.AddExportedValue<IMapper>(mapper);

                container.Compose(batch);
                container.ComposeParts(this);
                Logger.Info("配置MEF成功");

            }
            catch (Exception ex)
            {
                Logger.Info(ex.Message);
                Logger.Error(ex);
                throw;
            }

        }



        protected override object GetInstance(Type service, string key)
        {
            string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(service) : key;
            var exports = container.GetExportedValues<object>(contract).ToList();
            if (exports.Any())
            {
                return exports.First();
            }
            string errMsg = $"Could not locate any instances of contract : {contract}";
            Logger.Info(errMsg);
            throw new Exception(errMsg);
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return container.GetExportedValues<object>(AttributedModelServices.GetContractName(service));
        }

        protected override void BuildUp(object instance)
        {
            container.SatisfyImportsOnce(instance);
        }

        protected override async void OnStartup(object sender, StartupEventArgs e)
        {
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

            await DisplayRootViewForAsync<IMainViewModel>();
        }

        protected override void OnExit(object sender, EventArgs e)
        {
            base.OnExit(sender, e);
            this.Application.Shutdown();
        }

        #region 初始化方法
        /// <summary>
        /// 注册数据库服务
        /// </summary>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private IFreeSql AddDb()
        {
            try
            {
                Logger.Info("开始注册数据库服务");
                var fsql = DBHelper.RegisterFreeSql(SystemConfig.ConnectionString, SystemConfig.EnableMonitorDb);
                Logger.Info("完成注册数据库服务");
                string[] assemblyNames = SystemConfig.EntityAssemblyName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                //同步程序集中实体类与表结构
                DBHelper.SyncStructure(fsql, assemblyNames);
                return fsql;
            }
            catch (Exception ex)
            {
                Logger.Info($"数据连接异常:{ex.Message}");
                Logger.Info(ex.StackTrace);
                throw new Exception("数据连接异常");
            }
        }
        #endregion

        /// <summary>
        /// 导出服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetService<T>()
        {
            return container.GetExportedValue<T>();
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            // 处理异步任务中的异常
            HandException(e.Exception);
            e.SetObserved();
        }

        /// <summary>
        /// 错误全局捕捉
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected override void OnUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            HandException(e.Exception);
            // 设为已处理，防止应用程序崩溃
            e.Handled = true;
        }

        /// <summary>
        /// 统一全局错误异常处理
        /// </summary>
        /// <param name="e"></param>
        public void HandException(Exception e)
        {
            Caliburn.Micro.Execute.OnUIThread(() =>
            {
                // 处理异常，比如记录日志、显示错误信息等
                MessageBox.Show($"发生未处理的异常: {e.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            });
        }
    }
}